<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>浏览器工作原理以及 V8 引擎 | TBlog</title>
    <meta name="description" content="TBlog with vitePress">
    <link rel="stylesheet" href="/interview/assets/style.9156a4ed.css">
    <link rel="modulepreload" href="/interview/assets/Home.b86443e2.js">
    <link rel="modulepreload" href="/interview/assets/app.49accf37.js">
    <link rel="modulepreload" href="/interview/assets/Browser_index.md.9938c247.lean.js">
    <link rel="modulepreload" href="/interview/assets/app.49accf37.js">
    <link rel="icon" href="/favicon.ico">
    <meta name="twitter:title" content="浏览器工作原理以及 V8 引擎 | TBlog">
    <meta property="og:title" content="浏览器工作原理以及 V8 引擎 | TBlog">
  </head>
  <body>
    <div id="app"><!--[--><div class="theme"><header class="nav-bar" data-v-7161a24b><div class="sidebar-button" data-v-7161a24b><svg class="icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z" class></path></svg></div><a class="nav-bar-title" href="/interview/" aria-label="TBlog, back to home" data-v-7161a24b data-v-4a583abe><!----> TBlog</a><div class="flex-grow" data-v-7161a24b></div><div class="nav" data-v-7161a24b><nav class="nav-links" data-v-7161a24b data-v-15acbf05><!--[--><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="http://101.43.7.188:66" target="_blank" rel="noopener noreferrer" data-v-641633f9>Music <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="http://101.43.7.188:80" target="_blank" rel="noopener noreferrer" data-v-641633f9>CMC <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="https://juejin.cn/user/2163479676978734/posts" target="_blank" rel="noopener noreferrer" data-v-641633f9>掘金 <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="https://gitee.com/tu_zhiwei98" target="_blank" rel="noopener noreferrer" data-v-641633f9>Gitee <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><!--]--><!----><!----></nav></div><!--[--><!--]--></header><aside class="sidebar" data-v-6b49cdcd><nav class="nav-links nav" data-v-6b49cdcd data-v-15acbf05><!--[--><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="http://101.43.7.188:66" target="_blank" rel="noopener noreferrer" data-v-641633f9>Music <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="http://101.43.7.188:80" target="_blank" rel="noopener noreferrer" data-v-641633f9>CMC <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="https://juejin.cn/user/2163479676978734/posts" target="_blank" rel="noopener noreferrer" data-v-641633f9>掘金 <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="https://gitee.com/tu_zhiwei98" target="_blank" rel="noopener noreferrer" data-v-641633f9>Gitee <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><!--]--><!----><!----></nav><!--[--><!--]--><ul class="sidebar-links" data-v-6b49cdcd><!--[--><li class="sidebar-link"><p class="sidebar-link-item">Vue3.2X</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/">基本语法&amp;使用</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/VueX">VueX4.x</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/Router">Router4.x</a><!----></li><li class="sidebar-link"><p class="sidebar-link-item">部分源码解析</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/reactive">响应式系统</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/source/Watch">Watch</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/source/nextTick">nextTick</a><!----></li></ul></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">WebPack</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/">基础配置</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/optimize">优化方案</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/common">常见的Loader以及Plugin</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/custom">自定义Loader以及Plugin</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/advanced">手写简单的MY_Webpack</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">Javascript</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Javascript/">基本语法</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Javascript/advanced">高级语法</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">TypeScript</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/TypeScript/">基本语法</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/TypeScript/combat">业务实战</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/TypeScript/advanced">高阶使用</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">浏览器相关</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item active" href="/interview/Browser/">基本原理</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#v8-引擎的原理">V8 引擎的原理</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#v8-引擎从下载-js-到-执行一段-js-代码的过程">V8 引擎从下载 js 到 执行一段 JS 代码的过程</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#js-代码的执行过程-js-引擎的基本工作流程">JS 代码的执行过程 js 引擎的基本工作流程</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#_2-生成字节码">2. 生成字节码</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#_3-执行代码以及处理的优化">3. 执行代码以及处理的优化</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#js-代码的执行过程">JS 代码的执行过程</a><!----></li></ul></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Browser/plugin">浏览器插件</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Browser/advanced">深入原理</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">计算机网络</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Network/">计算机网络</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Network/security">前端安全</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">HTML/CSS</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/CSS/">CSS</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/HTML/">HTML</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">Vite2.X</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vite/">基础配置</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vite/optimize">原理以及优化</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">Node</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Node/">基本知识</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Node/pit">踩坑记录</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">其他前端工具</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Git/">Git</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Jenkins/">Jenkins</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/npm/">包管理工具</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">踩坑记录以及经验</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Pit/">踩坑</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/solution/">一些解决方案</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">面经</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Interview/">xxx面试</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Interview/two">xxX面试</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">个人学习历程</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Myself/">个人情况说明</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Myself/pre">入行工作前</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Myself/one">工作第一年</a><!----></li></ul></li><!--]--></ul><!--[--><!--]--></aside><!-- TODO: make this button accessible --><div class="sidebar-mask"></div><main class="page" data-v-7eddb2c4><div class="container" data-v-7eddb2c4><!--[--><!--]--><div style="position:relative;" class="content" data-v-7eddb2c4><div><h1 id="浏览器工作原理以及-v8-引擎"><a class="header-anchor" href="#浏览器工作原理以及-v8-引擎" aria-hidden="true">#</a> 浏览器工作原理以及 V8 引擎</h1><h2 id="v8-引擎的原理"><a class="header-anchor" href="#v8-引擎的原理" aria-hidden="true">#</a> <strong>V8 引擎的原理</strong></h2><p>V8 是用 C ++编写的 Google 开源高性能 JavaScript 和 WebAssembly 引擎，它用于 Chrome 和 Node.js 等。</p><p>它实现 ECMAScript 和 WebAssembly，并在 Windows 7 或更高版本，macOS 10.12+和使用 x64，IA-32， ARM 或 MIPS 处理器的 Linux 系统上运行。</p><p>V8 可以独立运行，也可以嵌入到任何 C ++应用程序中</p><p><strong>浏览器内核一般就是指浏览器的排版引擎, 页面渲染引擎 ,或者样板引擎</strong></p><h4 id="浏览器的渲染过程流程图"><a class="header-anchor" href="#浏览器的渲染过程流程图" aria-hidden="true">#</a> 浏览器的渲染过程流程图</h4><p>当浏览器下载 index.html 资源遇到了 js 标签之后 会先暂停 HTML 的解析 先去加载 js 代码</p><img src="/interview/assets/浏览器渲染过程.e7e0d626.png" alt="浏览器渲染过程" style="zoom:100%;"><h2 id="v8-引擎从下载-js-到-执行一段-js-代码的过程"><a class="header-anchor" href="#v8-引擎从下载-js-到-执行一段-js-代码的过程" aria-hidden="true">#</a> V8 引擎从下载 js 到 执行一段 JS 代码的过程</h2><p>站在 V8 的角度，理解其中的执行机制，也能够帮助我们理解很多的上层应用，包括 Babel、Eslint、前端框架的底层机制。那么，一段 JavaScript 代码放在 V8 当中究竟是如何执行的呢？</p><p>首先需要明白的是，机器是读不懂 JS 代码，机器只能理解特定的机器码，那如果要让 JS 的逻辑在机器上运行起来，就必须将 JS 的代码翻译成机器码，然后让机器识别。JS 属于解释型语言，对于解释型的语言说，解释器会对源代码做如下分析:</p><ul><li>Scanner 通过词法分析和语法分析生成 tokens(一个个的单元对象)</li><li>通过 parser 直接转成 AST(抽象语法树) or 预解析 是 v8 <strong>延迟解析</strong>的方案,作用是将不必要的函数进行预解析,只是解析暂时需要的内容,而全量解析是在函数调用的时候才会进行</li><li>然后会被 Ignition 转成字节码</li></ul><p>然后解释器根据字节码来执行程序。但 JS 整个执行的过程其实会比这个更加复杂，接下来就来一一地拆解。</p><h3 id="js-代码的执行过程-js-引擎的基本工作流程"><a class="header-anchor" href="#js-代码的执行过程-js-引擎的基本工作流程" aria-hidden="true">#</a> JS 代码的执行过程 js 引擎的基本工作流程</h3><p>js 引擎会在执行代码之前，会在堆内存中创建一个全局对象：Global Object（GO）</p><ul><li>该对象 所有的作用域（scope）都可以访问；</li><li>里面会包含 Date、Array、String、Number、setTimeout、setInterval 等等；</li><li>其中还有一个 window 属性指向自己；</li></ul><p><strong>执行上下文栈（调用栈）</strong></p><p>js 引擎内部有一个<strong>执行上下文栈（Execution Context Stack，简称 ECS）</strong>，它是用于执行<strong>代码的调用栈</strong>。</p><p>一些概念的解释:</p><p>FEC : 函数执行上下文 *<em>Global Execution Context（FEC）</em></p><p>GEC : 全局执行上下文 *<em>Global Execution C ontext（GEC）</em></p><p>ECS : *执行上下文栈（Execution Context Stack，简称 ECS）<strong>，它是用于执行</strong>代码的调用栈**。</p><ul><li><p>会被放到 ECS 中执行</p><ol><li><p>执行前:: 在 parser 转成 AST 的过程中，会将全局定义的变量、函数等加入到 GlobalObject 中，</p><p>但是并不会赋值； <strong>这个过程也称之为变量的作用域提升（hoisting）</strong></p></li><li><p>在代码执行中，对变量赋值，或者执行其他的函数</p></li></ol><img src="/interview/assets/GEC被放入到ECS中.8d4792ed.png" alt="EC被放入到ECS中" style="zoom:100%;"><p><strong>执行过程</strong><img src="/interview/assets/GEC执行过程.edcdffe8.png" alt="GEC执行过程" style="zoom:100%;"></p></li></ul><p><strong>函数的执行过程</strong></p><p>在执行的过程中<strong>执行到一个函数时</strong>，就会根据<strong>函数体</strong>创建一个<strong>函数执行上下文（Functional Execution Context，</strong></p><p><strong>简称 FEC）</strong>，并且压入到<strong>EC Stack</strong>中。</p><p>FEC 中包含三部分内容：</p><ol><li><p>在解析函数成为 AST 树结构时，会创建一个 Activation Object（AO）：AO 中包含形参、arguments、函数定义和指向函数对象、定义的变量；</p></li><li><p>作用域链：由 VO（在函数中就是 AO 对象）和父级 VO 组成，查找时会一层层查找；</p></li><li><p>this 绑定的值</p></li></ol><img src="/interview/assets/FEC内容.1da6b4e2.png" alt="FEC内容" style="zoom:100%;"><p><strong>FEC 放入 ECS 中</strong></p><img src="/interview/assets/FEC被放入ECS中.cf3a0e11.png" alt="FEC被放入ECS中" style="zoom:100%;"><hr><p><strong>FEC 的执行过程</strong><img src="/interview/assets/FEC执行过程.e12895d5.png" alt="FEC执行过程" style="zoom:100%;"></p><p>1.生成 AST</p><p>生成 AST 分为两步——词法分析和语法分析。</p><p>词法分析即分词，它的工作就是将一行行的代码分解成一个个 token。 比如下面一行代码:</p><div class="language-js"><pre><code><span class="token keyword">let</span> name <span class="token operator">=</span> <span class="token string">&quot;sanyuan&quot;</span><span class="token punctuation">;</span>
复制代码<span class="token punctuation">;</span>
</code></pre></div><p>其中会把句子分解成四个部分:</p><p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/11/23/16e96b7d3513ebf5~tplv-t2oaga2asx-watermark.awebp" alt="img"></p><p>即解析成了四个 token，这就是词法分析的作用。</p><p>接下来语法分析阶段，将生成的这些 token 数据，根据一定的语法规则转化为 AST。举个例子:</p><div class="language-js"><pre><code><span class="token keyword">let</span> name <span class="token operator">=</span> <span class="token string">&quot;sanyuan&quot;</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>最后生成的 AST 是这样的:</p><p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/11/23/16e96b7ff6b0f513~tplv-t2oaga2asx-watermark.awebp" alt="img"></p><p>当生成了 AST 之后，编译器/解释器后续的工作都要依靠 AST 而不是源代码。顺便补充一句，babel 的工作原理就是将 ES6 的代码解析生成<code>ES6的AST</code>，然后将 ES6 的 AST 转换为 <code>ES5 的AST</code>,最后才将 ES5 的 AST 转化为具体的 ES5 代码</p><h3 id="_2-生成字节码"><a class="header-anchor" href="#_2-生成字节码" aria-hidden="true">#</a> 2. 生成字节码</h3><p>开头就已经提到过了，生成 AST 之后，直接通过 V8 的解释器(也叫 Ignition)来生成字节码。但是<code>字节码</code>并不能让机器直接运行，那你可能就会说了，不能执行还转成字节码干嘛，直接把 AST 转换成机器码不就得了，让机器直接执行。确实，在 V8 的早期是这么做的，但后来因为机器码的体积太大，引发了严重的内存占用问题。</p><p>给一张对比图让大家直观地感受以下三者代码量的差异:</p><p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/11/23/16e96b822da9857c~tplv-t2oaga2asx-watermark.awebp" alt="img"></p><p>很容易得出，字节码是比机器码轻量得多的代码。那 V8 为什么要使用字节码，字节码到底是个什么东西？</p><blockquote><p>字节码是介于 AST 和 机器码之间的一种代码，但是与特定类型的机器码无关，字节码需要通过解释器将其转换为机器码然后执行。</p></blockquote><p>字节码仍然需要转换为机器码，但和原来不同的是，现在不用一次性将全部的字节码都转换成机器码，而是通过解释器来逐行执行字节码，省去了生成二进制文件的操作，这样就大大降低了内存的压力。</p><h3 id="_3-执行代码以及处理的优化"><a class="header-anchor" href="#_3-执行代码以及处理的优化" aria-hidden="true">#</a> 3. 执行代码以及处理的优化</h3><p>接下来，就进入到字节码解释执行的阶段啦！</p><p>在执行字节码的过程中，如果发现某一部分代码重复出现，那么 V8 将它记做<code>热点代码</code>(HotSpot)，然后将这么代码编译成<code>机器码</code>保存起来，这个用来编译的工具就是 V8 的<code>编译器</code>(也叫做<code>TurboFan</code>) , 因此在这样的机制下，代码执行的时间越久，那么执行效率会越来越高，因为有越来越多的字节码被标记为<code>热点代码</code>，遇到它们时直接执行相应的机器码，不用再次将转换为机器码。</p><p>其实当你听到有人说 JS 就是一门解释器语言的时候，其实这个说法是有问题的。因为字节码不仅配合了解释器，而且还和编译器打交道，所以 JS 并不是完全的解释型语言。而编译器和解释器的 根本区别在于前者会编译生成二进制文件但后者不会。</p><p>并且，这种字节码跟编译器和解释器结合的技术，我们称之为<code>即时编译</code>, 也就是我们经常听到的<code>JIT</code>。</p><p>这就是 V8 中执行一段 JS 代码的整个过程，梳理一下:</p><ol><li>首先通过词法分析和语法分析生成 <code>AST</code></li><li>将 AST 转换为字节码</li><li>由解释器逐行执行字节码，遇到热点代码启动编译器进行编译，生成对应的机器码, 以优化执行效率</li></ol><p>关于这个问题的拆解就到这里，希望对你有所启发。</p><ol start="4"><li><h3 id="js-代码的执行过程"><a class="header-anchor" href="#js-代码的执行过程" aria-hidden="true">#</a> JS 代码的执行过程</h3></li></ol><ul><li>当代码被解析,V8 引擎内部会自动创建一个全局对象(GlobalObject ==&gt; GO)</li><li>然后开始运行代码 <ol><li>v8 为了执行代码,内部会有一个执行上下文栈(ECStack) 函数调用栈</li><li>当我们执行全局代码的时候,需要创建 全局执行上下纹(GEC) 全局代码需要执行的时候才会创建</li></ol></li></ul></div></div><footer class="page-footer" data-v-7eddb2c4 data-v-fb8d84c6><div class="edit" data-v-fb8d84c6><div class="edit-link" data-v-fb8d84c6 data-v-1ed99556><!----></div></div><div class="updated" data-v-fb8d84c6><!----></div></footer><div class="next-and-prev-link" data-v-7eddb2c4 data-v-38ede35f><div class="container" data-v-38ede35f><div class="prev" data-v-38ede35f><a class="link" href="/interview/TypeScript/advanced" data-v-38ede35f><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon icon-prev" data-v-38ede35f><path d="M19,11H7.4l5.3-5.3c0.4-0.4,0.4-1,0-1.4s-1-0.4-1.4,0l-7,7c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.2-0.1,0.5,0,0.8c0.1,0.1,0.1,0.2,0.2,0.3l7,7c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3c0.4-0.4,0.4-1,0-1.4L7.4,13H19c0.6,0,1-0.4,1-1S19.6,11,19,11z"></path></svg><span class="text" data-v-38ede35f>高阶使用</span></a></div><div class="next" data-v-38ede35f><a class="link" href="/interview/Browser/plugin" data-v-38ede35f><span class="text" data-v-38ede35f>浏览器插件</span><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon icon-next" data-v-38ede35f><path d="M19.9,12.4c0.1-0.2,0.1-0.5,0-0.8c-0.1-0.1-0.1-0.2-0.2-0.3l-7-7c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l5.3,5.3H5c-0.6,0-1,0.4-1,1s0.4,1,1,1h11.6l-5.3,5.3c-0.4,0.4-0.4,1,0,1.4c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3l7-7C19.8,12.6,19.9,12.5,19.9,12.4z"></path></svg></a></div></div></div><!--[--><!--]--></div></main></div><!----><!--]--></div>
    <script>__VP_HASH_MAP__ = JSON.parse("{\"index.md\":\"992e2bc4\",\"css_advanced.md\":\"157298f3\",\"css_index.md\":\"0df1ef28\",\"browser_advanced.md\":\"a7a79457\",\"browser_index.md\":\"9938c247\",\"browser_plugin.md\":\"fd27046d\",\"git_index.md\":\"fb33a92a\",\"html_advanced.md\":\"599ad3d5\",\"html_index.md\":\"c94736b6\",\"interview_index.md\":\"07dc8acc\",\"interview_two.md\":\"0ca812f6\",\"javascript_advanced.md\":\"5c434e6d\",\"javascript_index.md\":\"d996a3fc\",\"jenkins_index.md\":\"3068e232\",\"myself_index.md\":\"340fc837\",\"myself_one.md\":\"31202d59\",\"myself_pre.md\":\"aa93248e\",\"network_index.md\":\"7251e8b9\",\"network_security.md\":\"d11dae3c\",\"node_index.md\":\"e0b22fc7\",\"node_pit.md\":\"a1502c64\",\"npm_index.md\":\"59b033b6\",\"pit_index.md\":\"603d46aa\",\"solution_index.md\":\"987aa705\",\"typescript_advanced.md\":\"431b8bba\",\"typescript_combat.md\":\"60c9a8a2\",\"typescript_index.md\":\"bd88b5a2\",\"vite_index.md\":\"d6838c03\",\"vite_optimize.md\":\"49f1bb24\",\"vue_index.md\":\"380ec221\",\"vue_reactive.md\":\"206c8e46\",\"vue_router.md\":\"0d556c25\",\"vue_source.md\":\"592e192a\",\"vue_vuex.md\":\"032502ef\",\"webpack_advanced.md\":\"ae6c63b7\",\"webpack_common.md\":\"141deb7a\",\"webpack_custom.md\":\"4827ebf8\",\"webpack_index.md\":\"49f185a6\",\"webpack_optimize.md\":\"545698f9\",\"vue_source_index.md\":\"1c12bc29\",\"vue_source_nexttick.md\":\"4533a28b\",\"vue_source_watch.md\":\"0e7342fc\"}")</script>
    <script type="module" async src="/interview/assets/app.49accf37.js"></script>
  </body>
</html>